#ifndef DW_GRAFFITI_SHADER_H
#	define DW_GRAFFITI_SHADER_H

#include "enums.h"

namespace dw {
	namespace graffiti {

template< GLenum shaderType >
struct Shader
{
public : //! @name State
	//! @{
	bool isValid() const
	{
		if (m_id != 0 && glIsShader(m_id) == GL_TRUE)
		{
			GLint params = 0;

			glGetShaderiv(m_id, GL_DELETE_STATUS, &params);

			return params == GL_FALSE;
		}

		return false;
	}

	bool isCompiled() const
	{
		if (isValid())
		{
			GLint params = 0;

			glGetShaderiv(m_id, GL_COMPILE_STATUS, &params);

			return params == GL_TRUE;
		}

		return false;
	}
	//! @}
	
protected : //! @name Construction & Destruction
	//! @{
	Shader(const char** sources, dw::uint32 sourcesCount)
	:	m_id(glCreateShader(shaderType))
	{
		dwAssert(sources != NULL, "Invalid parameter: sources is null");

		glShaderSource(m_id, sourcesCount, sources, NULL);
		glCompileShader(m_id);

		if (!isCompiled())
		{
			GLint logLength = 0;
			glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &logLength);

			std::vector<char> logStr(logLength);
			glGetShaderInfoLog(m_id, logLength, NULL, &logStr[0]);

			dwLogWarn("Shader compilation failed %s\n", &logStr[0]);
		}
	}

	~Shader()
	{
		glDeleteShader(m_id);
	}
	//! @}

protected : //! @name Data
	//! @{
	GLuint m_id;

	friend class Program;
	//! @}

private : //! @name Copy protection
	//! @{
	Shader(const Shader& ref);
	//! @}
};

	} // namespace graffiti
} // namespace dw

#endif // !DW_GRAFFITI_SHADER_H
